package com.newland.esp.common.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPReply;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import java.util.UUID;

/**
 * @see(功能介绍) : 上传文件至ftp服务器的工具类
 * @version(版本号) : 1.0
 * @author(创建人) : Dylan
 * @since : JDK 1.8
 */
public class FTPUtil {

    private static Logger logger = LoggerFactory.getLogger(FTPUtil.class);

    /**
     * 文件上传成功返回上传文件在服务器中的文件名
     *
     * @param host ftp服务器地址
     * @param port ftp服务器端口
     * @param username ftp服务器用户名
     * @param password ftp服务器密
     * @param fileName 上传文件名
     * @param inputStream 输入流
     * @param path ftp服务器上传路径
     * @return
     */
    public static String fileUpload(String host, Integer port, String username, String password,
                                    String fileName, InputStream inputStream, String path) {
        // 1、创建FTPClient对象
        FTPClient ftpClient = new FTPClient();
        // 保存FTP控制连接使用的字符集，必须在连接前设置
        ftpClient.setControlEncoding("UTF-8");
//		InputStream local = null;
        String remote = null;

        try {
            // 2、指定服务器地址（端口）
            ftpClient.connect(host, port);

            // 3、指定用户名和密码
            ftpClient.login(username, password);

            // 连接成功或者失败返回的状态码
            int reply = ftpClient.getReplyCode();
            // 如果reply返回230表示成功，如果返回530表示无密码或用户名错误或密码错误或用户权限问题。
            System.out.println(reply);
            // 具体的搜索“FTP上传常见错误详解”
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect();
                return null;
            }

            // 4、本地输入流
//			File file = new File("E:\\flower.jpg");
//			local = new FileInputStream(file);

            // 5、指定上传的路径 如果没有需要创建
            // 上传文件路径
//			String path = "/home/ftpuser/ego/img/test";

            /********************************************************/
			/*boolean hasPath = ftpClient.changeWorkingDirectory(path);
			if (!hasPath) {
				// 创建目录
				ftpClient.makeDirectory(path);
				// 重新指定上传的路径
				ftpClient.changeWorkingDirectory(path);
			}*/
            /********************************************************/

            /*****************创建目录 一次只能创建一个目录*****************/
            String basePath = "";
            for (String p : path.split("/")) {
                basePath += (p + "/");
                // 判断目录是否已经存在
                boolean hasPath = ftpClient.changeWorkingDirectory(basePath);
                if (!hasPath) {
                    // 创建目录 一次只能创建一个目录
                    ftpClient.makeDirectory(basePath);
                }
            }

            // 重新指定上传的路径
            ftpClient.changeWorkingDirectory(path);
            /*******************************************************/

            // 6、指定上传方式为二进制方式
            ftpClient.setFileType(FTP.BINARY_FILE_TYPE);

            // 得到文件后缀
            String suffix = fileName.substring(fileName.lastIndexOf("."));
            System.out.println("文件后缀为：" + suffix);

            remote = UUID.randomUUID().toString() + suffix;
            // 7、remote指定上传远程服务器的文件名 local指本地的输入流
            ftpClient.storeFile(remote, inputStream);
        } catch (SocketException e) {
            logger.error("文件上传连接错误：" + e.getMessage());
        } catch (IOException e) {
            logger.error("文件上传失败：" + e.getMessage());
        } finally {
            try {
                if (inputStream != null)
                    inputStream.close();

                ftpClient.logout();

                if (ftpClient.isConnected()) {
                    ftpClient.disconnect();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return remote;
    }


    /**
     * 文件删除成功与否返回一个boolean
     *
     * @param host
     * @param port
     * @param username
     * @param password
     * @param pathName
     * @param path
     * @return
     */
    public static boolean fileDelete(String host, Integer port, String username, String password,
                                     String pathName, String path) {
        // 1、创建FTPClient对象
        FTPClient ftpClient = new FTPClient();
        // 保存FTP控制连接使用的字符集，必须在连接前设置
        ftpClient.setControlEncoding("UTF-8");
        // 删除成功与否返回值
        boolean result = false;

        try {
            // 2、指定服务器地址（端口）
            ftpClient.connect(host, port);

            // 3、指定用户名和密码
            ftpClient.login(username, password);

            // 连接成功或者失败返回的状态码
            int reply = ftpClient.getReplyCode();
            // 如果reply返回230表示成功，如果返回530表示无密码或用户名错误或密码错误或用户权限问题。
            System.out.println(reply);
            // 具体的搜索“FTP上传常见错误详解”
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpClient.disconnect();
                logger.error("用户名或密码错误或用户权限问题！");
                return result;
            }

            String[] pathArray = pathName.split("/");
            // 拼接删除路径
            path += "/" + pathArray[3] + "/" + pathArray[4] + "/" + pathArray[5];

            String basePath = "/";
            for (String p : path.split("/")) {
                basePath += (p + "/");
                // 判断目录是否已经存在
                boolean hasPath = ftpClient.changeWorkingDirectory(basePath);
                if (!hasPath) {
                    logger.error("删除失败，目录不存在！");
                    return result;
                }
            }

            result = ftpClient.deleteFile(path + "/" + pathArray[6]);
            if (!result)
                logger.error("删除失败，文件不存在！");
        } catch (IOException e) {
            logger.error("删除失败：" + e.getMessage());
        } finally {
            try {
                ftpClient.logout();

                if (ftpClient.isConnected()) {
                    ftpClient.disconnect();
                }
            } catch (IOException e) {
                logger.error("删除失败：" + e.getMessage());
            }
        }
        return result;
    }

}
